package com.study.example.gameserver.module.buff.manager;

import com.google.common.base.Preconditions;
import com.sparrow.common.util.PackageUtil;
import com.sparrow.common.util.PropertiesUtil;
import com.sparrow.resource.cache.ResourceCache;
import com.sparrow.common.buff.domain.Buff;
import com.sparrow.common.buff.effect.IBuffEffect;
import com.sparrow.common.buff.effect.anno.BuffEffect;
import com.sparrow.common.buff.listener.BuffListener;
import com.study.example.gameserver.module.buff.resource.BuffResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Component
public class BuffManager {

    private static Logger logger = LoggerFactory.getLogger(BuffManager.class);

    private Map<String, Class<? extends IBuffEffect>> effectTypeClassMap = new HashMap<>();

    @Autowired
    private ResourceCache<Integer, BuffResource> buffResCache;

    @PostConstruct
    public void init() {
        String packageStr = PropertiesUtil.getProperty("game.base-package");
        Set<Class<?>> classes = PackageUtil.scanClass(packageStr, classMetadata -> classMetadata.hasAnnotation(BuffEffect.class.getName()));
        for (Class<?> clazz : classes) {
            BuffEffect anno = clazz.getAnnotation(BuffEffect.class);
            effectTypeClassMap.put(anno.value(), (Class<? extends IBuffEffect>) clazz);
        }
        logger.info("加载buff效果 size{}", effectTypeClassMap.size());
    }

    public Buff createBuff(int buffCfgId) {
        BuffResource buffResource = buffResCache.getResource(buffCfgId);
        Preconditions.checkNotNull(buffResource);
        Buff buff = new Buff(buffCfgId, buffResource.getDuration(), buffResource.getMaxStack(), System.currentTimeMillis());
        IBuffEffect buffEffect = createBuffEffect(buffResource);
        buff.setEffect(buffEffect);
        buff.addListener(new BuffListener() {
            @Override
            public void onBuffAdded(Buff buff) {
                logger.info("添加buff:{}", buff.getConfigId());
            }

            @Override
            public void onBuffExpire(Buff buff) {
                logger.info("移除buff:{}", buff.getConfigId());
            }
        });
        return buff;
    }

    private IBuffEffect createBuffEffect(BuffResource buffResource) {
        Class<? extends IBuffEffect> effectClass = effectTypeClassMap.get(buffResource.getEffectType().toString());
        try {
            IBuffEffect buffEffect = effectClass.newInstance();
            return buffEffect;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


}
